package red.mlz.console.controller.game;

import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import red.mlz.console.annotations.VerifiedUser;
import red.mlz.console.domain.BaseDescriptionValueVo;
import red.mlz.console.domain.game.GameInfoVo;
import red.mlz.console.domain.game.GameItemVo;
import red.mlz.console.domain.game.GameListVo;
import red.mlz.module.module.category.service.CategoryService;
import red.mlz.module.module.game.entity.Game;
import red.mlz.module.module.game.service.GameService;
import red.mlz.module.module.user.entity.User;
import red.mlz.module.utils.BaseUtils;
import red.mlz.module.utils.Response;
import red.mlz.module.utils.SpringUtils;

import javax.annotation.Resource;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
import java.util.stream.Stream;

@RestController
@Slf4j
public class GameController {
    @Resource
    private GameService gameService;
    @Resource
    private CategoryService categoryService;

    @RequestMapping("/game/list")
    public Response getConsoleGameInfo(@VerifiedUser User loginUser,
                                       @RequestParam Integer page,
                                       @RequestParam(required = false) String gameName) {

        if (BaseUtils.isEmpty(loginUser)) {
            return new Response(1002);
        }

        String pageSize = SpringUtils.getProperty("application.pageSize");
        Integer total = gameService.getTotalGames();
        List<Game> games = gameService.getAllGames(page, Integer.parseInt(pageSize.trim()),gameName);

        List<GameItemVo> gameItems = games.stream()
                .map(game -> {
                    GameItemVo itemVO = new GameItemVo();
                    itemVO.setId(game.getId());
                    itemVO.setImage(game.getCoverImages());
                    itemVO.setGameName(game.getGameName());
                    itemVO.setPlayerNumber(game.getPlayerNumber());
                    return itemVO;
                })
                .collect(Collectors.toList());

        GameListVo result = new GameListVo();
        result.setList(gameItems);
        result.setTotal(total);

        return new Response(1001,result);
    }

    @RequestMapping("/game/info")
    public Response getGameInfo(@VerifiedUser User loginUser,
                                @RequestParam Long gameId) {
        if (BaseUtils.isEmpty(loginUser)){
            return new Response(1002);
        }

        Game game = gameService.getById(gameId);
        if (game == null) {
            return null;
        }
        GameInfoVo gameInfoVO = new GameInfoVo();
        gameInfoVO.setTitle(game.getTitle());
        gameInfoVO.setCreateTime(BaseUtils.timeStamp2Date(game.getCreateTime()));
        gameInfoVO.setCoverImages(Collections.singletonList(game.getCoverImages()));
        gameInfoVO.setGameName(game.getGameName());
        gameInfoVO.setReleaseDate(game.getReleaseDate());
        gameInfoVO.setPrice(game.getPrice());
        gameInfoVO.setCategoryId(game.getCategoryId());
        try {
            List<BaseDescriptionValueVo> descriptions = JSON.parseArray(game.getGameDescription(), BaseDescriptionValueVo.class);
            gameInfoVO.setGameDescription(descriptions);
        }catch (Exception e){
            return new Response(4004,e.getMessage());
        }
        gameInfoVO.setRating(game.getRating());
        gameInfoVO.setUpdateTime(BaseUtils.timeStamp2Date(game.getUpdateTime()));

        return new Response(1001,gameInfoVO);

    }

    @RequestMapping("/game/add")
    public Response addGame(@VerifiedUser User loginUser,
                            @RequestParam(name = "gameId", required = false) Long gameId,
                            @RequestParam(name = "gameName") String gameName,
                            @RequestParam(name = "playerNumber") Long playerNumber,
                            @RequestParam(name = "title") String title,
                            @RequestParam(name = "coverImages") String coverImages,
                            @RequestParam(name = "releaseDate") String releaseDate,
                            @RequestParam(name = "price") Float price,
                            @RequestParam(name = "categoryId") Long categoryId,
                            @RequestParam(name = "gameDescription") String gameDescription,
                            @RequestParam(name = "rating") Float rating,
                            @RequestParam(name = "tags",required = false)String tags) {
        if (BaseUtils.isEmpty(loginUser)){
            return new Response(1002);
        }

        try {
            Long resultGameId = gameService.edit(gameId, gameName, playerNumber,
                    title, coverImages, releaseDate, price, categoryId, gameDescription, rating,tags);
            return new Response(1001,resultGameId);
        } catch (Exception e) {
            return new Response(4004,e.getMessage());
        }
    }

    @RequestMapping("/game/update")
    public Response updateGame(@VerifiedUser User loginUser,
                               @RequestParam(name = "gameId") Long gameId,
                               @RequestParam(name = "gameName") String gameName,
                               @RequestParam(name = "playerNumber") Long playerNumber,
                               @RequestParam(name = "title") String title,
                               @RequestParam(name = "coverImages") String coverImages,
                               @RequestParam(name = "releaseDate") String releaseDate,
                               @RequestParam(name = "price") Float price,
                               @RequestParam(name = "categoryId") Long categoryId,
                               @RequestParam(name = "gameDescription") String gameDescription,
                               @RequestParam(name = "rating") Float rating,
                               @RequestParam(name = "tags",required = false)String tags) {


        if (BaseUtils.isEmpty(loginUser)){
            return new Response(1002);
        }

        try {

            Long GameId = gameService.edit(gameId, gameName.trim(), playerNumber,
                    title.trim(), coverImages, releaseDate.trim(), price,
                    categoryId, gameDescription, rating,tags);
            return new Response(1001,GameId.toString());
        }catch (Exception e) {
            return new Response(4004,e.getMessage());
        }
    }

    @RequestMapping("/game/delete")
    public Response deleteGame(@VerifiedUser User loginUser,
                               @RequestParam(name = "gameId", required = false) Long gameId,
                               @RequestParam(name = "categoryId", required = false) Long categoryId) {
        if (BaseUtils.isEmpty(loginUser)){
            return new Response(1002);
        }
        // 参数校验：必须且仅提供一个参数
        if (Stream.of(gameId, categoryId).filter(Objects::nonNull).count() != 1) {
            return new Response(4004,"必须提供且仅提供一个参数：gameId 或 categoryId");
        }

        try {
            if (gameId != null) {
                // 删除游戏
                int isDeleted = gameService.delete(gameId);
                if (isDeleted == 0) {
                    return new Response<>(4004,"未找到对应游戏，删除失败");
                }
                return new Response<>(1001,"游戏删除成功");
            } else {
                // 删除分类及其关联游戏
                int isCategoryDeleted = categoryService.delete(categoryId);
                if (isCategoryDeleted == 0) {
                    return new Response(4004,"未找到对应分类，删除失败");
                }

                // 获取并删除关联游戏
                List<Game> games = gameService.findCategoryId(categoryId);
                if (!games.isEmpty()) {
                    List<Long> gameIds = games.stream()
                            .map(Game::getId)
                            .collect(Collectors.toList());
                    gameService.listDeletedByGameId(gameIds);
                    // 可根据需要检查是否全部删除成功
                }
                return new Response(1001,"分类及其关联游戏删除成功");
            }
        } catch (Exception e) {
            return new Response(4004,"删除过程中发生错误: " + e.getMessage());
        }
    }
}

